package com.lynn.common.utils.spf

import android.content.Context
import androidx.core.content.edit
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKey

/**
 * @description: 存储一些需要加密的轻量数据，比如Token ，密码等
 * @author: bailing
 * @datetime: 2025/6/4 06:56
 **/
 class SpfEncryptUtils(ctx: Context, fileName: String) {

    companion object {
        // 防止重排
        @Volatile
        private var instance: SpfEncryptUtils? = null

        // This function returns an instance of the SpfUtils class
        fun getInstance(ctx: Context, fileName: String, encryt: Boolean = false): SpfEncryptUtils {
            // If the instance is null, it will create a new instance of SpfUtils
            return instance ?: synchronized(this) {
                // If the instance is still null, it will create a new instance of SpfUtils
                instance ?: SpfEncryptUtils(ctx.applicationContext, fileName).also {
                    instance = it
                }
            }
        }
    }

    private val spf by lazy {
        val masterKey = MasterKey.Builder(ctx)
            .setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
            .build()
        EncryptedSharedPreferences.create(
            ctx,
            fileName,
            masterKey,
            EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
            EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
        )

    }


    fun <T> put(key: String, value: T) {
        when (value) {
            is String -> spf.edit { putString(key, value) }
            is Int -> spf.edit { putInt(key, value) }
            is Boolean -> spf.edit { putBoolean(key, value) }
            is Float -> spf.edit { putFloat(key, value) }
            is Long -> spf.edit { putLong(key, value) }
        }
    }

    @Suppress("UNCHECKED_CAST")
    fun <T> get(key: String, default: T): T {
        return when (default) {
            is String -> spf.getString(key, default) as T
            is Int -> spf.getInt(key, default) as T
            is Boolean -> spf.getBoolean(key, default) as T
            is Float -> spf.getFloat(key, default) as T
            is Long -> spf.getLong(key, default) as T
            else -> throw IllegalArgumentException("Unsupported type")
        }
    }

    fun remove(key: String) {
        spf.edit { remove(key) }
    }

    fun clear() {
        spf.edit { clear() }
    }

    fun contains(key: String): Boolean {
        return spf.contains(key)
    }

}